home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 February: Tool Chest / Apple Developer CD Series Tool Chest February 1996 (Apple Computer)(1996).iso / Sample Code / AOCE Sample Code / PowerTalk Access Modules / Sample SMSAM / SampleSMSAM Source / VirtualFile / VirtualASMacFile.cp < prev    next >
Encoding:
Text File  |  1995-07-28  |  16.0 KB  |  586 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        VirtualASMacFile.cp
  3.  
  4.     Copyright:    © 1991-1994 by Apple Computer, Inc.
  5.                 All rights reserved.
  6.  
  7.     Part of the AOCE Sample SMSAM Package.  Consult the license
  8.     which came with this software for your specific legal rights.
  9.  
  10. */
  11.  
  12.  
  13.  
  14. #ifndef __BLJSTANDARDINCLUDES__
  15. #include "BLJStandardIncludes.h"
  16. #endif
  17.  
  18. #ifndef __VAPPLESINGLEMACFILE__
  19. #include "VirtualASMacFile.h"
  20. #endif
  21.  
  22. #ifndef __DEBUGGINGGEAR__
  23. #include "DebuggingGear.h"
  24. #endif
  25.  
  26. #ifndef __ERRORS__
  27. #include <Errors.h>
  28. #endif
  29.  
  30. #ifndef __UTILITIES__
  31. #include "Utilities.h"
  32. #endif
  33.  
  34. #ifndef __VIRTUALFILE__
  35. #include "VirtualFile.h"
  36. #endif
  37.  
  38. #pragma segment VirtualAppleSingleFile
  39.  
  40. /***********************************|****************************************/
  41.  
  42. struct AppleSingleFileHeaderRecord
  43. {
  44.     long            magicNumber;
  45.     long            versionNumber;
  46.     unsigned char    homeFileSystem[16];
  47.     unsigned short    numberOfEntries;
  48. };
  49.  
  50. /***********************************|****************************************/
  51.  
  52. const unsigned long kAppleSingleMagicNumber = 0x00051600;
  53. const unsigned long kAppleSingleVersionNumber = 0x00010000;
  54.  
  55. /***********************************|****************************************/
  56.  
  57. struct AppleSingleFileEntryRecord
  58. {
  59.     long            entryID;
  60.     unsigned long    offset;
  61.     unsigned long    length;
  62. };
  63.  
  64. /***********************************|****************************************/
  65.  
  66. const unsigned long    kAppleSingleEntryDataFork = 1;
  67. const unsigned long    kAppleSingleEntryResourceFork = 2;
  68. const unsigned long    kAppleSingleEntryRealName = 3;
  69. const unsigned long    kAppleSingleEntryComment = 4;
  70. const unsigned long    kAppleSingleEntryBWIcon = 5;
  71. const unsigned long    kAppleSingleEntryColorIcon = 6;
  72. const unsigned long    kAppleSingleEntryFileInfo = 7;
  73. const unsigned long    kAppleSingleEntryFileDatesInfo = 8;
  74. const unsigned long    kAppleSingleEntryFinderInfo = 9;
  75. const unsigned long    kAppleSingleEntryMacintoshFileInfo = 10;
  76. const unsigned long    kAppleSingleEntryProDOSFileInfo    = 11;
  77. const unsigned long    kAppleSingleEntryMSDOSFileInfo = 12;
  78. const unsigned long    kAppleSingleEntryAFPShortName = 13;
  79. const unsigned long    kAppleSingleEntryAFPFileInfo = 14;
  80. const unsigned long    kAppleSingleEntryAFPDirectoryID = 15;
  81.  
  82. /***********************************|****************************************/
  83.  
  84. static OSErr vFSReadFrom (TVirtualFile *vF, long offset, long& count, void *data) {
  85.     if (vF)
  86.     {
  87.         vF->SetPosition (fsFromStart, offset);
  88.         return vF->ReadData (data, count);
  89.     }
  90.     return paramErr;
  91. }
  92.  
  93. /***********************************|****************************************/
  94.  
  95. #if debug
  96. Str255& DateToStr ( unsigned long secs )
  97. {
  98.     static    Str255 result;
  99.     Str255    temp1;
  100.     
  101.     IUDateString ( secs, shortDate, result );
  102.     
  103.     IUTimeString ( secs, true, temp1 );
  104.     PLstrcat ( result, "\p ");
  105.     PLstrcat ( result, temp1 );
  106.     
  107.     return result;
  108. }
  109. #endif
  110.  
  111. /***********************************|****************************************/
  112.  
  113. TVirtualAppleSingleMacFile::TVirtualAppleSingleMacFile (TVirtualFile *baseFile) 
  114. {
  115.     VOLATILE(baseFile);
  116.  
  117.     TRY
  118.         fAppleSingleBaseFile = nil;
  119.         fDataForkOffset = fDataForkLength = fDataForkFPos = 0;
  120.         fResourceForkOffset = fResourceForkLength = fResourceForkFPos = 0;
  121.  
  122.         FAILNULL (baseFile);
  123.  
  124.         long fileSize = 0;
  125.         FAILOSErr (baseFile->GetEnd (fileSize));
  126.         FAILOSErr(baseFile->SetPosition (fsFromStart, 0));
  127.  
  128. #if debug
  129.         if (keithFlag.Flag(12)) {
  130.             keith << "TVirtualAppleSingleMacFile:: baseFile size=" << fileSize << endl << flush;
  131.             keith << "FILE DATA:" << endl;
  132.  
  133.             {
  134.                 Ptr    data = FAILNewPtr(fileSize);
  135.                 if (data) {
  136.                     long dataSize = fileSize;
  137.                     vFSReadFrom(baseFile, 0, dataSize, (void*) data);
  138.                     DumpHex(keith, (char*) data, dataSize);
  139.                 }
  140.  
  141.                 DeallocatePtr((Ptr) data);
  142.             }
  143.         }
  144. #endif
  145.  
  146.         //    Verify that there is an AppleSingle file header on this file.
  147.         AppleSingleFileHeaderRecord appleSingleFileHeader;
  148.         long dataSize = sizeof(appleSingleFileHeader);
  149.         long offset = 0;
  150.         FAILOSErr ( vFSReadFrom (baseFile, offset, dataSize, &appleSingleFileHeader));
  151.  
  152.         if (appleSingleFileHeader.magicNumber != kAppleSingleMagicNumber) {
  153.             FAIL (-1);
  154.         }
  155.  
  156.         offset += sizeof(appleSingleFileHeader);
  157.  
  158.         //    OK.  The file has what appears to be an AppleSingle header.  Loop through,
  159.         //    reading each file entry record.
  160.         for (unsigned short entriesLeft = appleSingleFileHeader.numberOfEntries ; entriesLeft; --entriesLeft) {
  161.             AppleSingleFileEntryRecord        fileEntry;
  162.             long dataSize = sizeof(fileEntry);
  163.  
  164.             FAILOSErr (vFSReadFrom (baseFile, offset, dataSize, &fileEntry));
  165.  
  166.             switch (fileEntry.entryID) {
  167.                 case kAppleSingleEntryDataFork:
  168.                     fDataForkOffset = fileEntry.offset;
  169.                     fDataForkLength = fileEntry.length;
  170.  
  171.                     keithF( 21, "AppleSingle: fDataForkOffset=" << fDataForkOffset << " length=" << fDataForkLength );
  172.                     break;
  173.  
  174.                 case kAppleSingleEntryResourceFork:
  175.                     fResourceForkOffset = fileEntry.offset;
  176.                     fResourceForkLength = fileEntry.length;
  177.  
  178.                     keithF( 21, "AppleSingle: fResourceForkOffset=" << fResourceForkOffset << " length=" << fResourceForkLength );
  179.                     break;
  180.  
  181.                 case kAppleSingleEntryRealName: {
  182.                     long dataSize = shortmin(sizeof(fFileName), fileEntry.length);
  183.                     FAILOSErr (vFSReadFrom (baseFile, fileEntry.offset, dataSize, &fFileName[0]));
  184.  
  185.                     keithF( 21, "AppleSingle: realFileName=" << fFileName );
  186.  
  187.                     #if debug
  188.                     if (fFileName[0] + 1 != dataSize) {
  189.                         keith << "AppleSingle: REAL FILE NAME DOES NOT APPEAR TO BE A STR32! ("
  190.                             << dataSize << " vs. " << (short) fFileName[0] + 1 << ")" << endl << flush;
  191.                     }
  192.                     #endif
  193.                     break;
  194.                 }
  195.  
  196.                 case kAppleSingleEntryFinderInfo: {
  197.                     long dataSize = shortmin(sizeof(fFinderInfo), fileEntry.length);
  198.                     FAILOSErr (vFSReadFrom (baseFile, fileEntry.offset, dataSize, &fFinderInfo));
  199.  
  200.                     keithF( 21, "AppleSingle: fFinderInfo, type="; OutputOSType(keith, fFinderInfo.fdType); keith << " creator="; OutputOSType(keith, fFinderInfo.fdCreator); keith << " flags=" << fFinderInfo.fdFlags );
  201.                     break;
  202.                 }
  203.  
  204.                 case kAppleSingleEntryComment:
  205.                 case kAppleSingleEntryBWIcon:
  206.                 case kAppleSingleEntryColorIcon:
  207.                 default:
  208.                     keithF( 21, "AppleSingle: entry ignored #" << fileEntry.entryID << " @ offset=" << offset << " length=" << fileEntry.length );
  209.                     break;
  210.  
  211.                 case kAppleSingleEntryFileInfo:
  212.                 {
  213.                     typedef struct AppleSingleVersionOneFileDatesInfoStruct {
  214.                         unsigned long creationDate;
  215.                         unsigned long modificationDate;
  216.                         unsigned long backupDate;
  217.                         unsigned long accessDate;
  218.                     } AppleSingleVersionOneFileDatesInfoStruct;
  219.                     
  220.                     if ( fileEntry.length >= sizeof( AppleSingleVersionOneFileDatesInfoStruct ) )
  221.                     {    AppleSingleVersionOneFileDatesInfoStruct relevantDates;
  222.                         long dataSize = sizeof(relevantDates);
  223.     
  224.                         FAILOSErr (vFSReadFrom (baseFile, fileEntry.offset, dataSize, &relevantDates));
  225.  
  226.                         fCreationDate = relevantDates.creationDate;
  227.                         fModificationDate = relevantDates.modificationDate;
  228.                         fBackupDate = relevantDates.backupDate;
  229.                     }
  230.                     else
  231.                     {
  232.                         fCreationDate = NowDateTime();
  233.                         fModificationDate = fCreationDate;
  234.                         fBackupDate = 0;
  235.                     }
  236.                     
  237.                     keithF( 12, "AppleSingle: (Version 1) creation=" << DateToStr( fCreationDate ) <<
  238.                                     " mod=" << DateToStr ( fModificationDate ) );
  239.                     break;
  240.                 }
  241.  
  242.                 case kAppleSingleEntryFileDatesInfo:
  243.                 {
  244.                     typedef struct AppleSingleFileDatesInfoStruct {
  245.                         signed long creationDate;
  246.                         signed long modificationDate;
  247.                         signed long backupDate;
  248.                         signed long accessDate;
  249.                     } AppleSingleFileDatesInfoStruct;
  250.                     
  251.                     signed long kDeltaBetweenAppleSingleDateAndMacintoshDate = - 3029529600;
  252.                     
  253.                     if ( fileEntry.length >= sizeof( AppleSingleFileDatesInfoStruct ) )
  254.                     {    AppleSingleFileDatesInfoStruct relevantDates;
  255.                         long dataSize = sizeof(relevantDates);
  256.     
  257.                         FAILOSErr (vFSReadFrom (baseFile, fileEntry.offset, dataSize, &relevantDates));
  258.  
  259.                         fCreationDate = relevantDates.creationDate + kDeltaBetweenAppleSingleDateAndMacintoshDate;
  260.                         fModificationDate = relevantDates.modificationDate + kDeltaBetweenAppleSingleDateAndMacintoshDate;
  261.                         fBackupDate = relevantDates.backupDate + kDeltaBetweenAppleSingleDateAndMacintoshDate;
  262.                     }
  263.                     else
  264.                     {
  265.                         fCreationDate = NowDateTime();
  266.                         fModificationDate = fCreationDate;
  267.                         fBackupDate = 0;
  268.                     }
  269.                     
  270.                     keithF ( 12, "AppleSingle: creation=" << DateToStr( fCreationDate ) <<
  271.                                     " mod=" << DateToStr ( fModificationDate ) );
  272.                     break;
  273.                 }
  274.  
  275.                 case kAppleSingleEntryMacintoshFileInfo:
  276.                 case kAppleSingleEntryProDOSFileInfo:
  277.                 case kAppleSingleEntryMSDOSFileInfo:
  278.                 case kAppleSingleEntryAFPShortName:
  279.                 case kAppleSingleEntryAFPFileInfo:
  280.                 case kAppleSingleEntryAFPDirectoryID:
  281.                     break;
  282.                 
  283.             }
  284.  
  285.             offset += sizeof(fileEntry);
  286.         }
  287.  
  288.         fAppleSingleBaseFile = baseFile;
  289.  
  290.     EXCEPTION
  291.         fAppleSingleBaseFile = nil;    // signals an error
  292.  
  293.     ENDEXCEPTION
  294.  
  295.     if (fAppleSingleBaseFile != nil)
  296.         fAppleSingleBaseFile->RegisterReference();
  297. }
  298.  
  299. /***********************************|****************************************/
  300.  
  301. TVirtualAppleSingleMacFile::~TVirtualAppleSingleMacFile() {
  302.     if (fAppleSingleBaseFile != nil) {
  303.         fAppleSingleBaseFile->UnregisterReference();
  304.     }
  305. }
  306.  
  307. /***********************************|****************************************/
  308.  
  309. OSErr TVirtualAppleSingleMacFile::Open () {
  310.     if (fAppleSingleBaseFile)
  311.         return noErr;
  312.  
  313.     return fnfErr;
  314. }
  315.  
  316. /***********************************|****************************************/
  317.  
  318. OSErr TVirtualAppleSingleMacFile::Close () {
  319.  
  320.     fDataForkFPos = 0;
  321.     fResourceForkFPos = 0;
  322.  
  323.     if (fAppleSingleBaseFile)
  324.         return noErr;
  325.  
  326.     return fnfErr;
  327. }
  328.  
  329. /***********************************|****************************************/
  330.  
  331. OSErr TVirtualAppleSingleMacFile::ReadData (void* buffer,long& count,TVirtualMacFile::ForkType whichFork) {
  332.     OSErr        result = noErr;
  333.     long        offset;
  334.  
  335.     if (fAppleSingleBaseFile == nil) {
  336.         keithF ( 12, "TVirtualASF::MReadData, bad apple single file" );
  337.         return fnfErr;
  338.     }
  339.  
  340.     switch (whichFork) {
  341.         case TVirtualMacFile::kData:
  342.             offset = fDataForkFPos + fDataForkOffset;
  343.             count = longmin (fDataForkLength - fDataForkFPos, count);
  344.             break;
  345.  
  346.         case TVirtualMacFile::kResource:
  347.             offset = fResourceForkFPos + fResourceForkOffset;
  348.             count = longmin(fResourceForkLength - fResourceForkFPos, count);
  349.             break;
  350.  
  351.         default:
  352.             keithF( 12, "TVirtualASF::MReadData, bad fork type" );
  353.             return fnfErr;
  354.     }
  355.  
  356.     if ((result = fAppleSingleBaseFile->SetPosition (fsFromStart, offset)) == noErr) {
  357.         result = fAppleSingleBaseFile->ReadData (buffer, count);
  358.     }
  359.  
  360.     switch (whichFork) {
  361.         case TVirtualMacFile::kData:
  362.             fDataForkFPos += count;
  363.             break;
  364.         case TVirtualMacFile::kResource:
  365.             fResourceForkFPos += count;
  366.             break;
  367.     }
  368.  
  369.     keithF( 21, "TVirtualASF::MReadData, result=" << result << " offset=" << offset << " count=" << count );
  370.  
  371.     return result;
  372. }
  373.  
  374. /***********************************|****************************************/
  375.  
  376. OSErr TVirtualAppleSingleMacFile::WriteData (const void* buffer, long& count, TVirtualMacFile::ForkType whichFork) {
  377.     unused (buffer);
  378.     unused (count);
  379.     unused (whichFork);
  380.  
  381.     // For the time being, don't allow writes.  Eventually, this should be revisited
  382.     // (especially if we 'genericize' this class for public use)
  383.     return wrPermErr;
  384. }
  385.  
  386. /***********************************|****************************************/
  387.  
  388. OSErr TVirtualAppleSingleMacFile::SetEnd (long logEof, TVirtualMacFile::ForkType whichFork) {
  389.     unused (logEof);
  390.     unused (whichFork);
  391.  
  392.     return wrPermErr;
  393. }
  394.  
  395. /***********************************|****************************************/
  396.  
  397. OSErr TVirtualAppleSingleMacFile::GetEnd (long& logEof, TVirtualMacFile::ForkType whichFork) const {
  398.     if (fAppleSingleBaseFile == nil) {
  399.         keithF( 21, "TVirtualASF::MGetEOF, bad apple single file" );
  400.         return paramErr;
  401.     }
  402.  
  403.     switch (whichFork) {
  404.         case TVirtualMacFile::kData:
  405.             logEof = fDataForkLength;
  406.             keithF( 21, "TVirtualASF::MGetEOF, data forkSize=" << logEof );
  407.             return noErr;
  408.             
  409.         case TVirtualMacFile::kResource:
  410.             logEof = fResourceForkLength;
  411.             keithF( 21, "TVirtualASF::MGetEOF, resource forkSize=" << logEof );
  412.             return noErr;
  413.     }
  414.  
  415.     keithF( 21, "TVirtualASF::MGetEOF, bad fork type" );
  416.  
  417.     logEof = 0;
  418.     return paramErr;
  419. }
  420.  
  421. /***********************************|****************************************/
  422.  
  423. OSErr TVirtualAppleSingleMacFile::SetPosition (short posMode, long posOffset, TVirtualMacFile::ForkType whichFork) {
  424.  
  425.     if (fAppleSingleBaseFile == nil) {
  426.         keithF( 21, "TVirtualASF::MSetFPos, bad apple single file." );
  427.         return fnfErr;
  428.     }
  429.  
  430.     OSErr result = paramErr;
  431.     switch (whichFork) {
  432.         case TVirtualMacFile::kData:
  433.             switch (posMode) {
  434.                 case fsFromStart:
  435.                     fDataForkFPos = longmax(0, longmin(fDataForkLength, posOffset));
  436.                     result = noErr;
  437.                     break;
  438.  
  439.                 case fsFromLEOF:
  440.                     fDataForkFPos = longmax(0, longmin(fDataForkLength, fDataForkLength - posOffset));
  441.                     result = noErr;
  442.                     break;
  443.  
  444.                 case fsFromMark:
  445.                     fDataForkFPos = longmax(0, longmin(fDataForkLength, fDataForkFPos + posOffset));
  446.                     result = noErr;
  447.                     break;
  448.  
  449.                 default:
  450.                     result = paramErr;
  451.                     break;
  452.             }
  453.  
  454.         case TVirtualMacFile::kResource:
  455.             switch (posMode) {
  456.                 case fsFromStart:
  457.                     fResourceForkFPos = longmax(0, longmin(fResourceForkLength, posOffset));
  458.                     result = noErr;
  459.                     break;
  460.  
  461.                 case fsFromLEOF:
  462.                     fResourceForkFPos = longmax(0, longmin(fResourceForkLength, fResourceForkLength - posOffset));
  463.                     result = noErr;
  464.                     break;
  465.  
  466.                 case fsFromMark:
  467.                     fResourceForkFPos = longmax(0, longmin(fResourceForkLength, fResourceForkFPos + posOffset));
  468.                     result = noErr;
  469.                     break;
  470.  
  471.                 default:
  472.                     result = paramErr;
  473.                     break;
  474.             }
  475.     }
  476.  
  477.     keithF( 21, "TVirtualASF::MSetFPos, err=" << result << " fDataPos=" << fDataForkFPos << " fResPos=" << fResourceForkFPos );
  478.  
  479.     return result;
  480. }
  481.  
  482. /***********************************|****************************************/
  483.  
  484. OSErr TVirtualAppleSingleMacFile::GetPosition (long& filePos,TVirtualMacFile::ForkType whichFork) const {
  485.     if (fAppleSingleBaseFile == nil) {
  486.         keithF( 21, "TVirtualASF::MGetFPos, bad apple single file." );
  487.         return fnfErr;
  488.     }
  489.  
  490.     OSErr result = paramErr;
  491.  
  492.     switch (whichFork) {
  493.         case TVirtualMacFile::kData:
  494.             filePos = fDataForkFPos;
  495.             result = noErr;
  496.             break;
  497.  
  498.         case TVirtualMacFile::kResource:
  499.             filePos = fResourceForkFPos;
  500.             result = noErr;
  501.             break;
  502.     }
  503.  
  504.     keithF( 21, "TVirtualASF::MGetFPos, fork " << (short) whichFork << " pos=" << filePos );
  505.  
  506.     return result;
  507. }
  508.  
  509. /***********************************|****************************************/
  510.  
  511. OSErr TVirtualAppleSingleMacFile::SetFinderInfo (const FInfo& finderInfo) {
  512.     unused (finderInfo);
  513.  
  514.     return wrPermErr;
  515. }
  516.  
  517. /***********************************|****************************************/
  518.  
  519. OSErr TVirtualAppleSingleMacFile::GetFinderInfo (FInfo& finderInfo) const {
  520.     finderInfo = fFinderInfo;
  521.  
  522.     return noErr;
  523. }
  524.  
  525. /***********************************|****************************************/
  526.  
  527. void TVirtualAppleSingleMacFile::SetUserRef(long ref) {
  528.     fUserRefNum = ref;
  529. }
  530.  
  531. /***********************************|****************************************/
  532.  
  533. long TVirtualAppleSingleMacFile::GetUserRef()  const{
  534.     return fUserRefNum;
  535. }
  536.  
  537. /***********************************|****************************************/
  538.  
  539. OSErr TVirtualAppleSingleMacFile::GetDate (unsigned long& dateTime, TVirtualMacFile::WhichDateType whichDate) const {
  540.     OSErr result = noErr;
  541.     
  542.     if ( whichDate == kCreationDate )
  543.         dateTime = fCreationDate;
  544.     else if ( whichDate == kModDate )
  545.         dateTime = fModificationDate;
  546.     else
  547.     {
  548.         dateTime = 0;
  549.         result = paramErr;
  550.     }
  551.     
  552.     return result;
  553. }
  554.  
  555. /***********************************|****************************************/
  556.  
  557. OSErr TVirtualAppleSingleMacFile::SetDate (unsigned long dateTime, TVirtualMacFile::WhichDateType whichDate) {
  558.     unused(whichDate);
  559.  
  560.     return wrPermErr;
  561. }
  562.  
  563. /***********************************|****************************************/
  564.  
  565. Boolean TVirtualAppleSingleMacFile::IsValidAppleSingleFile() const
  566. {
  567.     return (fAppleSingleBaseFile != nil);
  568. }
  569.  
  570. /***********************************|****************************************/
  571.  
  572. OSErr TVirtualAppleSingleMacFile::SetSpec ( const FSSpec& spec )
  573. {
  574.     PLstrcpy ( fFileName, spec.name );
  575.     return noErr;
  576. }
  577.  
  578. /***********************************|****************************************/
  579.  
  580. OSErr TVirtualAppleSingleMacFile::GetSpec ( FSSpec& spec ) const
  581. {
  582.     PLstrcpy ( spec.name, fFileName );
  583.     return noErr;
  584. }
  585.  
  586. /***********************************|****************************************/